{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Making line plots" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Import packages" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import matplotlib.pyplot as plt\n", "import matplotlib.animation as ani\n", "import IPython\n", "import os\n", "%matplotlib agg\n", "\n", "# import plons scripts\n", "import plons\n", "import plons.SmoothingKernelScript as sk\n", "import plons.PhysicalQuantities as pq\n", "import plons.ConversionFactors_cgs as cgs\n", "import plons.Plotting as plot" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Setting information about data" ] }, { "cell_type": "code", "execution_count": null, "metadata": {}, "outputs": [], "source": [ "prefix = \"wind\"\n", "loc = \"Model\"\n", "dumpnumber = 600\n", "dump = os.path.join(loc, f\"{prefix}_{dumpnumber:06d}\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Retrieving the data" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Creating the directory to store the models" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [], "source": [ "!mkdir -p $loc" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Downloading the data" ] }, { "cell_type": "code", "execution_count": 4, "metadata": {}, "outputs": [], "source": [ "%%capture\n", "if not os.path.exists(dump):\n", " !wget \"https://github.com/Ensor-code/phantom-models/raw/refs/heads/main/Esseldeurs+2023/BinaryHighLucy/wind_00600?download=\" --output-document $dump\n", "infile = os.path.join(loc, f\"{prefix}.in\")\n", "if not os.path.exists(infile):\n", " !wget \"https://raw.githubusercontent.com/Ensor-code/phantom-models/refs/heads/main/Esseldeurs%2B2023/BinaryHighLucy/wind.in\" --output-document $infile\n", "setupfile = os.path.join(loc, f\"{prefix}.setup\")\n", "if not os.path.exists(setupfile):\n", " !wget \"https://raw.githubusercontent.com/Ensor-code/phantom-models/refs/heads/main/Esseldeurs%2B2023/BinaryHighLucy/wind.setup\" --output-document $setupfile" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "### Loading setup and dump" ] }, { "cell_type": "code", "execution_count": 5, "metadata": {}, "outputs": [], "source": [ "setup = plons.LoadSetup(loc, prefix)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [], "source": [ "dumpData = plons.LoadFullDump(dump, setup)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Animation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "I will create an animation with a 2D slice plot on the left, and a line slice on the right." ] }, { "cell_type": "code", "execution_count": 7, "metadata": {}, "outputs": [], "source": [ "fig = plt.figure(figsize=(6, 3))\n", "\n", "ax = [None, None]\n", "ax[0] = plt.subplot2grid((1, 2), (0, 0))\n", "ax[1] = plt.subplot2grid((1, 2), (0, 1), aspect=ax[0].get_aspect())" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Creating 2D slice plot on the left" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "data": { "text/plain": [ "(,\n", " )" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "n = 500\n", "x = np.linspace(-30*cgs.au, 30*cgs.au, n)\n", "y = np.linspace(-30*cgs.au, 30*cgs.au, n)\n", "X, Y = np.meshgrid(x, y)\n", "Z = np.zeros_like(X)\n", "theta = pq.getPolarAngleCompanion(dumpData['posComp'][0], dumpData['posComp'][1])\n", "X_rot, Y_rot, Z_rot = sk.rotateMeshAroundZ(theta, X, Y, Z)\n", "smooth_rot = sk.smoothMesh(X_rot, Y_rot, Z_rot, dumpData, ['rho'])\n", "\n", "ax[0].set_aspect('equal')\n", "ax[0].set_facecolor('k')\n", "\n", "ax[0].pcolormesh(X/cgs.au, Y/cgs.au, np.log10(smooth_rot[\"rho\"]+1e-99), cmap=plt.colormaps['inferno'], vmin=-17, vmax = -14)\n", "ax[0].set_xlim(x[0]/cgs.au, x[-1]/cgs.au)\n", "ax[0].set_ylim(y[0]/cgs.au, y[-1]/cgs.au)\n", "\n", "plot.plotSink(ax[0], dumpData, setup, rotate=True)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Creating the line slices on the right" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Create a line plot, like in example 1. At the end, give the axis the same shape as the slice 2D plot" ] }, { "cell_type": "code", "execution_count": 9, "metadata": {}, "outputs": [], "source": [ "n = 100\n", "rx0 = np.array((np.linspace(0, 50, n), np.zeros(n), np.zeros(n))).transpose()*cgs.au\n", "theta0 = pq.getPolarAngleCompanion(dumpData['posComp'][0], dumpData['posComp'][1])\n", "rz = np.array((np.zeros(n), np.zeros(n), np.linspace(0, 50, n))).transpose()*cgs.au\n", "\n", "line0 = ax[0].plot(rx0[:,0], rx0[:,1], color=\"white\")[0]\n", "\n", "smoothx = sk.getSmoothingKernelledPix(10, dumpData, ['rho'], sk.rotatePixCoordAroundZ(theta0, rx0))\n", "smoothz = sk.getSmoothingKernelledPix(10, dumpData, ['rho'], rz)\n", "\n", "line1 = ax[1].plot(rx0[:,0]/cgs.au, np.log10(smoothx[\"rho\"]+1e-99))[0]\n", "ax[1].plot(rz[:,2]/cgs.au, np.log10(smoothz[\"rho\"]+1e-99))\n", "ax[1].set_xlim(0, 50)\n", "ax[1].set_ylim(-18, -13)\n", "\n", "posx0 = ax[0].get_position()\n", "posx1 = ax[1].get_position()\n", "ax[1].set_position([posx1.x0, posx0.y0, posx0.width, posx0.height])" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Defining what to update in each frame" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "In each frame, an angle theta will be returned. Create a line at this angle, calculate the smoothed values, and plot them on the figures" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [], "source": [ "def animate(theta):\n", " rx = sk.rotatePixCoordAroundZ(-theta, rx0)\n", " smoothx = sk.getSmoothingKernelledPix(100, dumpData, ['rho'], sk.rotatePixCoordAroundZ(theta0, rx))\n", "\n", " line0.set_data(rx[:,0], rx[:,1])\n", " line1.set_data(rx0[:,0]/cgs.au, np.log10(smoothx[\"rho\"]+1e-99))" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "#### Creating the animation" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "By creating the animation, the frames will represent the angles from the previous function. Interval represents the delay between frames in milliseconds." ] }, { "cell_type": "code", "execution_count": 11, "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "anim = ani.FuncAnimation(fig, animate, frames=np.linspace(0, 2*np.pi, 500, endpoint=False), interval=20)\n", "IPython.display.display(IPython.display.HTML(anim.to_html5_video()))\n", "plt.close()" ] } ], "metadata": { "kernelspec": { "display_name": "plons", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.10.14" }, "orig_nbformat": 4 }, "nbformat": 4, "nbformat_minor": 2 }